package co.za.alicrity.exactcover.linkedlist;

import java.util.List;

import co.za.alicrity.exactcover.ColumnHeader;
import co.za.alicrity.exactcover.Node;

public class LinkedListHelper<T extends LinkedList<E>,E extends ListNode<E>> {
	
	private T list;
	private Iterator<E> iterator;

	public LinkedListHelper(T list) {
		super();
		this.list = list;
	}
	
	public Iterator<E> getIterator(){
			return new Iterator<E>() {
				
				E cur = list.getFirst();

				@Override
				public boolean hasNext() {
					return cur!=null;
				}

				@Override
				public E getNext() {
					E ret = cur;
					cur=cur.getNext();
					return ret;
				}
			};
	}
	
	public void addNode(E node){
		if (list.getFirst()==null){
			list.setFirst(node);
			list.setLast(node);
			node.setNext(null);
			node.setPrevious(null);
		} else if (list.getFirst()==list.getLast()) {
			list.setLast(node);
			list.getLast().setPrevious(list.getFirst());
			list.getFirst().setNext(list.getLast());
		} else {
			list.getLast().setNext(node);
			node.setPrevious(list.getLast());
			list.setLast(node);
		}
	}
	
	public void removeNode(E node){
		
		if (node == list.getFirst()&& node ==list.getLast()){
			 list.setFirst(null);
			 list.setLast(null);			
		} else if (node == list.getFirst()) {
			list.setFirst(list.getFirst().getNext());
			list.getFirst().setPrevious(null);
			
			
		} else if(node == list.getLast()){
			list.setLast(list.getLast().getPrevious());
			list.getLast().setNext(null);
		}
		else{
			 node.getPrevious().setNext(node.getNext());
			 node.getNext().setPrevious(node.getPrevious());
		}
		 
		
		
	}
	
	public int getSize(){
		int size=0;
		Iterator<E> i = getIterator();
		while(i.hasNext()){
			size++;
			i.getNext();
		}
		return size;
	}

	public String getListString(){
		String n= "{";
		Iterator<E> i = getIterator();
		while(i.hasNext()){
			n+=i.getNext().toString();
		}
		n+="}";
		return n;
	}

	public void putBack(E node) {
		if (list.getFirst()==null){
			list.setFirst(node);
			list.setLast(node);
		}
		else if (node.getNext()==list.getFirst()){
			list.getFirst().setPrevious(node);
			list.setFirst(node);
		} else if (list.getLast()==node.getPrevious()){
			list.getLast().setNext(node);
			list.setLast(node);
		} else {
			node.getPrevious().setNext(node);
			node.getNext().setPrevious(node);
		}
	}
	

}
